<template>
  <div class="custom-body" :style="borderStyle">
    <div class="custom-content" :style="contentStyle">
      <div class="calendar-header">
        <div class="header-li">
          <el-date-picker
            v-model="calendar.month"
            placeholder="请选择月份"
            type="month"
            value-format="yyyy-MM"
            @change="updateValue(calendar.month)"
          />
        </div>
        <div class="header-li">
          我的日程
        </div>
        <div class="header-li">
          <el-button-group>
            <el-button
              type="primary"
              @click="preMonth"
            ><i class="el-icon-arrow-left" />上月</el-button>
            <el-button type="primary" @click="dateNow">本月</el-button>
            <el-button
              type="primary"
              @click="nextMonth"
            >下月<i
              class="el-icon-arrow-right"
            /></el-button>
          </el-button-group>
        </div>
      </div>
      <div class="calendar-table">
        <div class="calendar-table-body">
          <div class="table-th-first">
            <div class="table-th">星期天</div>
            <div class="table-th">星期一</div>
            <div class="table-th">星期二</div>
            <div class="table-th">星期三</div>
            <div class="table-th">星期四</div>
            <div class="table-th">星期五</div>
            <div class="table-th">星期六</div>
          </div>
          <div class="table-th">
            <div
              v-for="(item, index) in tableData"
              :key="'td-' + index"
              class="table-td"
              :class="getTableClass(item, index)"
              @click="addSchedule"
            >
              <el-tooltip v-if="value" effect="light" placement="right">
                <div class="table-th-body">{{ item.day }}</div>

                <template #content>
                  <div class="custom-tooltip-content">
                    <div class="custom-tooltip-title">
                      共{{ item.list.length }}个日程
                    </div>
                    <div
                      v-for="(obj, objId) in item.list"
                      :key="'content-' + index + '-' + objId"
                      class="custom-tooltip-li"
                    >
                      <div class="tooltip-left">
                        {{ obj.date }}
                      </div>
                      <div class="tooltip-right">
                        <div class="tooltip-right-li">
                          {{ obj.title }}
                        </div>
                        <div v-if="obj.FTitle" class="tooltip-right-li active">
                          {{ obj.FTitle }}
                        </div>
                        <div v-if="obj.location" class="tooltip-right-li active">
                          {{ obj.location }}
                        </div>
                      </div>
                      <i class="el-icon-delete" @click="handleDelete(objId, obj, scheduleDataList)" />
                    </div>
                  </div>
                </template>
              </el-tooltip>
              <div v-else class="table-th-body">{{ item.day }}</div>
              <div
                v-if="item.list !== undefined && item.list.length > 0"
                class="table-td-range"
              />
            </div>
            <AddSchedule ref="addSch" @init="init" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { template } from '@/mixins/template'
import { layout } from '@/mixins/layout'
import { dateFormat } from '@/utils/utils'
import { queryAllScheduleByPage, deleteObject } from '@/api/schedule/schedule'
import AddSchedule from './AddSchedule/AddSch.vue'

export default {
  name: 'Calandar',
  components: { AddSchedule },
  mixins: [template, layout],

  props: {
    data: {
      type: Array,
      default: function() {
        return []
      }
    }
  },
  data() {
    // 日期验证
    var validateDate = (rule, endTime, callback) => {
      // 验证日期（判断结束日期是否大于开始日期）日期格式为YY—MM—DD
      var startTime = this.form.kssj
      if (!endTime) {
        return callback(new Error('结束时间不能为空'))
      }
      setTimeout(() => {
        if (startTime.length > 0 && endTime.length > 0) {
          var sd = new Date(startTime)
          var ed = new Date(endTime)

          if (sd.getTime() > ed.getTime()) {
            callback(new Error('开始日期不能大于结束日期'))
          } else {
            callback()
          }
        }
      }, 1000)
    }
    return {
      value: new Date(),
      resDate: [],
      resultTime: [],
      calendar: {
        month: '',
        date: new Date()
      },
      form: {
        fqr: '',
        title: '',
        kssj: '',
        jssj: '',
        sfgk: true,
        rcjb: '',
        sysOrganizations: '',
        sysUserMembers: '',
        content: '',
        desc: ''
      },

      rules: {
        title: [{ required: true, message: '请输入日程标题', trigger: 'blur' }],
        kssj: [
          {
            required: true,
            message: '请选择开始时间',
            trigger: 'change'
          }
        ],
        jssj: [
          {
            required: true,
            validator: validateDate,
            message: '请选择结束时间且开始日期不能大于结束日期',
            trigger: 'change'
          }
        ],
        rcjb: [
          {
            required: true,
            message: '请选择日程级别',
            trigger: 'change'
          }
        ],
        content: [
          { required: true, message: '请描述日程内容', trigger: 'blur' }
        ]
      },
      tableData: [],
      scheduleDataList: []
    }
  },
  watch: {
    scheduleDataList() {
      // scheduleDataList有数据了，再触发下面的方法
      this.$nextTick(function() {
        this.dateNow()// 当前月
      })
    }
  },
  mounted: function() {
    this.init()
  },

  methods: {
    addSchedule() {
      // this.$nextTick作用是，当数据被修改后使用这个方法，会回调获取更新后的dom再渲染出来
      this.$nextTick(() => {
        this.$refs.addSch.openDialog(true)
      })
    },
    handleDelete(index, data, rows) {
      var userid = this.$store.getters.user.username
      if (data.fqr === userid) {
        if (data.id !== null && undefined !== data.id) {
          // 单个删除
          this.$confirm('此操作将永久删除该' + ', 是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
          }).then(() => {
            (async() => {
              try {
                const delResult = await deleteObject({ id: data.id })
                if (delResult.state === 200) {
                  this.$message.success('删除成功！')
                  this.init()
                } else {
                  this.$message.error('删除失败！')
                }
              } catch (error) {
                console.log(error)
              }
            })()
          })
        }
      }
    },
    getCurrentDate() {
      var nowTime = new Date().getTime()
      var currentTime = new Date(nowTime)
      var year = currentTime.getFullYear()
      var month = currentTime.getMonth() + 1
      var day = currentTime.getDate()
      return `${year}-${month}-${day}`
    },
    // 获取近期的日程数据
    init() {
      var d = this.getCurrentDate()
      this.map = []
      this.scheduleDataList = []
      // 分页获取日程信息
      queryAllScheduleByPage({
        page: 0,
        size: 100,
        datetime: d
      }).then(res => {
        var result = res.content
        // console.log(result)
        var code = res.state
        if (code === 200) {
          result.forEach(item => {
            var kssj = item.kssj.substring(0, 10)
            var jssj = item.jssj.substring(0, 10)

            if (typeof kssj === 'string') {
              const reg = /^\d{4}-(0?[1-9]|1[0-2])-((0?[1-9])|((1|2)[0-9])|30|31)$/g
              if (!reg.test(kssj)) {
                console.log(`开始时间：${kssj}时间格式错误`)
                return false
              }
            }
            if (typeof jssj === 'string') {
              const reg = /^\d{4}-(0?[1-9]|1[0-2])-((0?[1-9])|((1|2)[0-9])|30|31)$/g
              if (!reg.test(jssj)) {
                console.log(`结束时间：${jssj}时间格式错误`)
                return false
              }
            }
            let start = new Date(kssj)
            const end = new Date(jssj)
            const resultTime = []

            // 当 开始时间小于结束时间的时候进入循环
            while (start <= end) {
              const getDay = start.getDate()
              // 月份需要加 1
              const getMonth = start.getMonth() + 1
              const getYear = start.getFullYear()
              /**
               * 拼接时间格式
               * (getMonth >= 10 ? `${getMonth}` : `0${getMonth}`) 自动给 小于10的时间前面补0
               */
              const setTime =
                `${getYear}-` +
                (getMonth >= 10 ? `${getMonth}` : `0${getMonth}`) +
                '-' +
                (getDay >= 10 ? `${getDay}` : `0${getDay}`)

              resultTime.push(setTime)
              /**
               * 重新设置开始时间
               * 使用 setFullYear() 方法会自动将时间累加，返回的是时间戳格式
               * 使用 new Date() 将时间重新设置为标准时间
               * getMonth - 1 将月份时间重新还原
               */
              start = new Date(
                start.setFullYear(getYear, getMonth - 1, getDay + 1)
              )
            }
            resultTime.forEach(e => {
              var sch = {
                id: item.id,
                fqr: item.fqr,
                location: item.location,
                title: item.title,
                FTitle: item.name,
                kssj: item.kssj,
                jssj: item.jssj,
                date: e
              }
              this.scheduleDataList.push(sch)
            })
          })
        }
      })
    },
    // 数据绑定
    updateValue(info) {
      this.tableData.length = 0
      console.log(this.calendar, '日期')
      if (info === '' || info == null) {
        this.calendar.date = new Date()
      } else {
        this.calendar.date = new Date(info)
      }

      this.generateMonth(this.calendar.date)
    },
    getTableClass: (data, index) => {
      let className = ''
      if (data.type !== 0) {
        className = `${className} old`
      }
      if (index % 2 === 0) {
        className = `${className} active`
      }
      const date1 = dateFormat('yyyyMMdd', data.date)
      const date2 = dateFormat('yyyyMMdd', new Date())
      if (date1 === date2) {
        className = `${className} day`
      }
      return className
    },
    dateNow() {
      this.tableData.length = 0
      const date = new Date()
      this.generateMonth(date)
      this.calendar.date = date
    },
    // 下个月
    nextMonth() {
      this.tableData.length = 0
      const date = this.calendar.date
      const newDate = new Date(
        date.getFullYear(),
        date.getMonth() + 1,
        date.getDate(),
        date.getHours(),
        date.getMinutes(),
        date.getSeconds(),
        date.getMilliseconds()
      )
      this.generateMonth(newDate)
      this.calendar.date = newDate
    },
    // 上月
    preMonth() {
      this.tableData.length = 0
      const date = this.calendar.date
      const newDate = new Date(
        date.getFullYear(),
        date.getMonth() - 1,
        date.getDate(),
        date.getHours(),
        date.getMinutes(),
        date.getSeconds(),
        date.getMilliseconds()
      )
      this.generateMonth(newDate)
      this.calendar.date = newDate
    },
    // 构建日历数据
    generateMonth(date) {
      // console.log(this.scheduleDataList)
      date.setDate(1) // 本月第一天
      const endDate = new Date(date.getFullYear(), date.getMonth() + 1, 0)
      const dayEnd = endDate.getDate()
      const weekStart = date.getDay() // 开始周
      const weekEnd = endDate.getDay() // 本月结束周
      const milsStart = date.getTime()
      const dayMils = 24 * 60 * 60 * 1000
      const milsEnd = endDate.getTime() + dayMils
      let current
      // 上个月的几天
      for (let i = 0; i < weekStart; i++) {
        current = new Date(milsStart - (weekStart - i) * dayMils)
        const date = dateFormat('YYYY-MM-dd', current)
        const list = Array.isArray(this.scheduleDataList)
          ? this.scheduleDataList.filter(item => {
            if (item.date.indexOf(date) !== -1) {
              return item
            }
          })
          : []
        const listNew = list.map(item => {
          const newItem = {
            id: item.id,
            fqr: item.fqr,
            title: item.title,
            FTitle: item.FTitle,
            date: item.kssj.substring(item.kssj.lastIndexOf('-') + 3, item.kssj.length),
            location: item.location
          }
          return newItem
        })

        this.tableData.push({
          type: -1,
          date: current,
          fullYear: current.getFullYear().toString(),
          month: (current.getMonth() + 1).toString(),
          day: current.getDate().toString(),
          list: listNew
        })
      }
      // 当前月
      for (let i = 0; i < dayEnd; i++) {
        current = new Date(milsStart + i * dayMils)
        const date = dateFormat('YYYY-MM-dd', current)
        const list = Array.isArray(this.scheduleDataList)
          ? this.scheduleDataList.filter(item => {
            if (item.date.indexOf(date) !== -1) {
              return item
            }
          })
          : []
        const listNew = list.map(item => {
          const newItem = {
            id: item.id,
            fqr: item.fqr,
            title: item.title,
            FTitle: item.FTitle,
            date: item.kssj.substring(item.kssj.lastIndexOf('-') + 3, item.kssj.length),
            location: item.location
          }
          return newItem
        })

        this.tableData.push({
          type: 0,
          date: current,
          fullYear: current.getFullYear().toString(),
          month: (current.getMonth() + 1).toString(),
          day: current.getDate().toString(),
          list: listNew
        })
      }
      // 下个月的几天
      for (let i = 0; i < 6 - weekEnd; i++) {
        current = new Date(milsEnd + i * dayMils)
        const date = dateFormat('YYYY-MM-dd', current)
        const list = Array.isArray(this.scheduleDataList)
          ? this.scheduleDataList.filter(item => {
            if (item.date.indexOf(date) !== -1) {
              return item
            }
          })
          : []
        const listNew = list.map(item => {
          const newItem = {
            id: item.id,
            fqr: item.fqr,
            title: item.title,
            FTitle: item.FTitle,
            date: item.kssj.substring(item.kssj.lastIndexOf('-') + 3, item.kssj.length),
            location: item.location
          }
          return newItem
        })
        this.tableData.push({
          type: 1,
          date: current,
          fullYear: current.getFullYear().toString(),
          month: (current.getMonth() + 1).toString(),
          day: current.getDate().toString(),
          list: listNew
        })
      }
    }
  }
}
</script>

<style scoped lang="scss">
.custom-body {
  width: 100%;
  height: 100%;
  position: relative;
  display: flex;
  flex-flow: column nowrap;
  border-radius: 4px;
  box-sizing: border-box;
  overflow: hidden;
}
.custom-content {
  width: 100%;
  flex: 1 1 auto;
  padding: 0 20px;
  overflow: hidden;
  box-sizing: border-box;
  min-height: 300px;
  .calendar-header {
    height: 50px;
    line-height: 50px;
    display: flex;
    flex-flow: row nowrap;
    justify-content: space-between;
    overflow: hidden;
    margin-top: 15px;
    .header-li {
      line-height: 50px;
    }
  }
  .calendar-table {
    width: 100%;
    flex: 1 1;
    .calendar-table-body {
      width: 100%;
      height: 100%;
      border-radius: 6px;
      border-top: 1px solid #f6f6f6;
      border-left: 1px solid #f6f6f6;
      display: flex;
      flex-flow: column nowrap;
      min-height: 250px;
      .table-th-first {
        height: 50px;
        display: flex;
        flex-flow: row nowrap;
        .table-th {
          width: 14.285%;
          text-align: center;
          border-right: 1px solid #f6f6f6;
          border-bottom: 1px solid #f6f6f6;
          display: block;
          height: 50px;
          line-height: 50px;
        }
      }
      .table-th {
        flex: 1 1 auto;
        display: flex;
        flex-flow: row wrap;
        .table-td {
          width: 14.285%;
          box-sizing: border-box;
          border-right: 1px solid #f6f6f6;
          border-bottom: 1px solid #f6f6f6;
          padding: 10px;
          cursor: pointer;
          position: relative;
          .table-td-range {
            position: absolute;
            width: 10px;
            height: 10px;
            border-radius: 5px;
            background-color: #f56c6c;
            right: 5px;
            top: 5px;
          }
          .table-th-body {
            width: 100%;
            height: 100%;
            position: relative;
            font-size: 12px;
          }
        }
        .table-td.active {
          background-color: #f5f7fa;
        }
        .table-td:hover,
        .table-td.day {
          background-color: #ecf5ff;
        }
        .table-td.day {
          color: #409eff;
          .table-td-range {
            background-color: #e6a23c;
          }
        }
        .table-td.old {
          color: #a8abb2;
          .table-td-range {
            background-color: #67c23a;
          }
        }
      }
    }
  }
}
.custom-tooltip-content {
  width: 200px;
  min-height: 100px;
  padding-bottom: 20px;
  box-sizing: border-box;
  .custom-tooltip-title {
    width: 100%;
    height: 40px;
    line-height: 40px;
  }
  .custom-tooltip-li {
    min-height: 40px;
    width: 100%;
    display: flex;
    flex-flow: row nowrap;
    margin-top: 5px;
    .tooltip-left {
      width: 40px;
      text-align: left;
    }
    .tooltip-right {
      width: 160px;
      text-align: left;
      border-radius: 2px;
      border-left: 3px solid #409eff;
      background-color: #ebf5ff;
      padding-left: 10px;
      box-sizing: border-box;
      display: flex;
      flex-flow: column wrap;
      .tooltip-right-li {
        width: 100%;
      }
      .tooltip-right-li.active {
        color: #a8abb2;
      }
    }
  }
}
</style>

